package basics

import scala.math._

object Basics extends App {
    ////////////////// 以下来自快学scala 第1，2章
    println("this is scala basics")
    
    // 被隐式地转换成 StringOps对象
    println("hello".intersect("world"))
    // 同理 1 被转换成RichInt
    1.to(10)
    println(sqrt(2))
    // 没有参数且不改变对象 的方法不带圆括号
    println("hello".distinct)

    val x = 1
    // 如果写成 if (x>0) s=1 else s=-1 ，则s 得为var
    val s = if (x>0) 1 else -1

    val anyVar = if (x>0) "positive" else -1
    // 赋值动作本身是没有值的，或者更严格说是Unit类型 ,所以下面这种写法不对
    //x = y = 1 // 把Unit 赋给了x

    // {} 包括一系列表达式，其结果也是一个表达式，块的最后一个表达式的值即是块的值

    // scala 没有 for(int i=0; i<n; i++)这样的
    var sum = 0
    for (i <- 1 to 10) {
        sum += i
        // break // 没有break,continue
    }
    println("sum:" + sum)

    val msg = "hello"
    for (i <- 0 until msg.length) { // 最后一个是 s.length -1
        sum += msg(i)
    }
    println("sum:" + sum)

    // 支持提供多个生成器
    for (i<- 1 to 3; j <- 1 to 3) print((i+j) + " ")
    println()
    // 支持给生成器带一个guard
    for (i <- 1 to 3; j <- 1 to 3 if i != j) print((i + j) + " ")
    println()
    // 里面可以定义变量
    for (i <- 1 to 3; from = 4-i; j <- from to 3) print((i + j) + " ")
    println()

    // 如果想要多行写，则这样
    for { i <- 1 to 3
        from = 4-i
        j <- from to 3
    } print((i+j) + " ")
    println

    // 这里生成一个集合, 属于for 推导式
    for (i <- 1 to 10) yield i % 3

    // 只要不是递归的，可以不指定返回值
    def fac(n :Int) = {
        var r = 1
        for (i <- 1 to n) r = r * i
        // 最后一个表达式的值就是函数的返回值
        r
    }
    println(fac(5))

    def facRecursive(n: Int) : Int = if (n <=0) 1 else n * facRecursive(n-1)

    def decorateWithDefaultPara(str: String, left: String = "[", right: String = "]") = 
        left + str + right
    println(decorateWithDefaultPara("abc"))
    println(decorateWithDefaultPara("abc", ">>>["))
    println(decorateWithDefaultPara("abc", right = ">>", left = "<<"))

    // 函数参数 实际是Seq[T] 类型
    def variableFunc(args: Int*) = {
        var res = 0
        for (arg <- args) res += arg
        res
    }
    println(variableFunc(1,2))
    println(variableFunc(1,2, 3))

    def recursiveSum(args: Int*): Int = {
        if (args.length == 0) 0
        else args.head + recursiveSum(args.tail: _*)
    }
    // 如果传的是整数区间，则显式告诉编译器当做参数序列来传
    println("recursive sum with variable parameter: " + recursiveSum(0 to 5: _*))

    // 对于无返回值的函数叫做procedure，可以不写 =
    def noReturnValueFunc() {
        println("no return value func")
    }

    // 关于异常，scala不支持受检异常，即不在函数后写 throws ***
}